package cn.juque.jdfsystem.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.juque.common.constants.NumberConstant;
import cn.juque.common.constants.StringConstants;
import cn.juque.jdfsystem.bo.StatisticsCountBO;
import cn.juque.jdfsystem.bo.StatisticsFileBO;
import cn.juque.jdfsystem.cache.TpsCache;
import cn.juque.jdfsystem.entity.FileInfo;
import cn.juque.jdfsystem.entity.RegisterInfo;
import cn.juque.jdfsystem.enums.RegisterExecuteStatusEnum;
import cn.juque.jdfsystem.service.IStatisticsService;
import cn.juque.lucenecandy.core.base.CountQueryWrapperBuilder;
import cn.juque.lucenecandy.core.base.QueryWrapperBuilder;
import cn.juque.lucenecandy.helper.IndexHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.search.BooleanClause;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author juque
 * @version 1.0.0
 * <ul>
 *     <li>StatisticsServiceImpl</li>
 * </ul>
 * @date 2023-05-06 11:05:03
 **/
@Slf4j
@Service("statisticsService")
public class StatisticsServiceImpl implements IStatisticsService {

    @Resource
    private IndexHelper indexHelper;

    @Resource
    private TpsCache tpsCache;

    /**
     * 统计数量
     *
     * @return StatisticsCountBO
     */
    @Override
    public StatisticsCountBO count() {
        StatisticsCountBO statisticsCountBO = new StatisticsCountBO();
        statisticsCountBO.setOnLineInstance(NumberConstant.ZERO);
        statisticsCountBO.setTotalInstance(NumberConstant.ZERO);
        statisticsCountBO.setUploadTps(0.00);
        statisticsCountBO.setDownloadTps(0.00);
        QueryWrapperBuilder<RegisterInfo> registerBuilder = new QueryWrapperBuilder<>(RegisterInfo.class);
        List<RegisterInfo> registerInfoList = this.indexHelper.search(registerBuilder.build());
        if (CollUtil.isNotEmpty(registerInfoList)) {
            long onlineCount = registerInfoList.stream()
                    .filter(f -> RegisterExecuteStatusEnum.NORMAL.getCode().equals(f.getExecuteStatus())).count();
            statisticsCountBO.setOnLineInstance((int) onlineCount);
            statisticsCountBO.setTotalInstance(registerInfoList.size());
        }
        CountQueryWrapperBuilder<FileInfo> countFileBuilder = new CountQueryWrapperBuilder<>(FileInfo.class);
        Long fileCount = this.indexHelper.count(countFileBuilder.build());
        statisticsCountBO.setFileCount(fileCount);
        statisticsCountBO.setUploadTps(this.tpsCache.getUploadTps());
        statisticsCountBO.setDownloadTps(this.tpsCache.getDownloadTps());
        return statisticsCountBO;
    }

    /**
     * 统计文件数量
     *
     * @param days 统计的天数
     * @return StatisticsFileBO
     */
    @Override
    public StatisticsFileBO fileCount(Integer days) {
        StatisticsFileBO statisticsFileBO = new StatisticsFileBO();
        Date current = new Date();
        List<Integer> dates = new ArrayList<>(days);
        for(int i =0;i<= days;i++) {
            String date = DateUtil.format(DateUtil.offsetDay(current, - i), DatePattern.PURE_DATE_PATTERN);
            dates.add(Integer.parseInt(date));
        }
        List<String> result = dates.parallelStream().map(m->{
            CountQueryWrapperBuilder<FileInfo> countFileBuilder = new CountQueryWrapperBuilder<>(FileInfo.class);
            countFileBuilder.matchInt(FileInfo::getCreateDate, m, BooleanClause.Occur.MUST);
            long count = this.indexHelper.count(countFileBuilder.build());
            return m + StringConstants.COLON + count;
        }).collect(Collectors.toList());
        result = result.stream()
                .sorted(Comparator.comparing(s-> CharSequenceUtil.subBefore(s, StringConstants.COLON, false)))
                .collect(Collectors.toList());
        List<String> dayList = result.stream().map(m->
                CharSequenceUtil.subBefore(m, StringConstants.COLON, false)).collect(Collectors.toList());
        statisticsFileBO.setDayList(dayList);
        List<Integer> fileCounts = result.stream().map(m->
                Integer.parseInt(CharSequenceUtil.subAfter(m, StringConstants.COLON, false)))
                .collect(Collectors.toList());
        statisticsFileBO.setFileCountList(fileCounts);
        return statisticsFileBO;
    }
}
